#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
PDF2DOCX API服务
简洁版本 - 提供PDF转Word的Web服务
"""

from flask import Flask, request, jsonify, send_file, render_template
from pdf2docx import Converter
import os
import uuid
import tempfile
from datetime import datetime
import traceback
import fitz  # PyMuPDF
from werkzeug.utils import secure_filename

app = Flask(__name__)

# 配置
UPLOAD_FOLDER = 'temp_uploads'
OUTPUT_FOLDER = 'temp_outputs'
MAX_FILE_SIZE = 50 * 1024 * 1024  # 50MB
ALLOWED_EXTENSIONS = {'pdf'}

# 创建临时文件夹
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(OUTPUT_FOLDER, exist_ok=True)

def allowed_file(filename):
    """检查文件是否为PDF"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def get_pdf_info(pdf_path):
    """获取PDF基本信息"""
    try:
        doc = fitz.open(pdf_path)
        info = {
            'pages': len(doc),
            'title': doc.metadata.get('title', ''),
            'has_text': False,
            'has_images': False
        }
        
        # 检查前3页内容
        for page_num in range(min(3, len(doc))):
            page = doc[page_num]
            text = page.get_text().strip()
            images = page.get_images()
            
            if len(text) > 50:
                info['has_text'] = True
            if images:
                info['has_images'] = True
        
        doc.close()
        return info
    except Exception as e:
        return {'error': str(e)}

@app.route('/')
def welcome():
    """欢迎页面 - 选择使用方式"""
    return render_template('welcome.html')

@app.route('/converter')
def converter():
    """转换器页面 - 网页转换工具"""
    return render_template('index.html')

@app.route('/api-demo')
def api_demo():
    """API演示页面"""
    return render_template('api_demo.html')
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
PDF2DOCX API服务
简洁版本 - 提供PDF转Word的Web服务
"""

from flask import Flask, request, jsonify, send_file, render_template
from pdf2docx import Converter
import os
import uuid
import tempfile
from datetime import datetime
import traceback
import fitz  # PyMuPDF
from werkzeug.utils import secure_filename

app = Flask(__name__)

# 配置
UPLOAD_FOLDER = 'temp_uploads'
OUTPUT_FOLDER = 'temp_outputs'
MAX_FILE_SIZE = 50 * 1024 * 1024  # 50MB
ALLOWED_EXTENSIONS = {'pdf'}

# 创建临时文件夹
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(OUTPUT_FOLDER, exist_ok=True)

def allowed_file(filename):
    """检查文件是否为PDF"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def get_pdf_info(pdf_path):
    """获取PDF基本信息"""
    try:
        doc = fitz.open(pdf_path)
        info = {
            'pages': len(doc),
            'title': doc.metadata.get('title', ''),
            'has_text': False,
            'has_images': False
        }
        
        # 检查前3页内容
        for page_num in range(min(3, len(doc))):
            page = doc[page_num]
            text = page.get_text().strip()
            images = page.get_images()
            
            if len(text) > 50:
                info['has_text'] = True
            if images:
                info['has_images'] = True
        
        doc.close()
        return info
    except Exception as e:
        return {'error': str(e)}

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
PDF2DOCX API服务
简洁版本 - 提供PDF转Word的Web服务
"""

from flask import Flask, request, jsonify, send_file, render_template
from pdf2docx import Converter
import os
import uuid
import tempfile
from datetime import datetime
import traceback
import fitz  # PyMuPDF
from werkzeug.utils import secure_filename

app = Flask(__name__)

# 配置
UPLOAD_FOLDER = 'temp_uploads'
OUTPUT_FOLDER = 'temp_outputs'
MAX_FILE_SIZE = 50 * 1024 * 1024  # 50MB
ALLOWED_EXTENSIONS = {'pdf'}

# 创建临时文件夹
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(OUTPUT_FOLDER, exist_ok=True)

def allowed_file(filename):
    """检查文件是否为PDF"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def get_pdf_info(pdf_path):
    """获取PDF基本信息"""
    try:
        doc = fitz.open(pdf_path)
        info = {
            'pages': len(doc),
            'title': doc.metadata.get('title', ''),
            'has_text': False,
            'has_images': False
        }
        
        # 检查前3页内容
        for page_num in range(min(3, len(doc))):
            page = doc[page_num]
            text = page.get_text().strip()
            images = page.get_images()
            
            if len(text) > 50:
                info['has_text'] = True
            if images:
                info['has_images'] = True
        
        doc.close()
        return info
    except Exception as e:
        return {'error': str(e)}

@app.route('/')
def index():
    """主页 - 显示上传界面"""
    return render_template('index.html')

@app.route('/api/info')
def api_info():
    """API信息"""
    return jsonify({
        'service': 'PDF2DOCX API',
        'version': '1.0.0',
        'description': 'PDF转Word文档转换服务',
        'max_file_size': f'{MAX_FILE_SIZE // (1024*1024)}MB',
        'endpoints': {
            'POST /api/convert': '转换PDF为Word',
            'POST /api/analyze': '分析PDF文件',
            'GET /api/info': '获取API信息'
        }
    })

@app.route('/api/analyze', methods=['POST'])
def analyze_pdf():
    """分析PDF文件"""
    try:
        if 'file' not in request.files:
            return jsonify({'success': False, 'error': '没有上传文件'}), 400
        
        file = request.files['file']
        if file.filename == '' or not allowed_file(file.filename):
            return jsonify({'success': False, 'error': '请上传PDF文件'}), 400
        
        # 保存临时文件
        filename = secure_filename(file.filename)
        temp_id = str(uuid.uuid4())
        temp_path = os.path.join(UPLOAD_FOLDER, f"{temp_id}_{filename}")
        file.save(pdf_path)
        
        try:
            # 分析PDF
            pdf_info = get_pdf_info(temp_path)
            os.remove(temp_path)  # 清理临时文件
            
            return jsonify({
                'success': True,
                'filename': filename,
                'info': pdf_info,
                'timestamp': datetime.now().isoformat()
            })
            
        except Exception as e:
            if os.path.exists(temp_path):
                os.remove(temp_path)
            raise e
            
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

@app.route('/api/convert', methods=['POST'])
def convert_pdf():
    """转换PDF为Word"""
    try:
        if 'file' not in request.files:
            return jsonify({'success': False, 'error': '没有上传文件'}), 400
        
        file = request.files['file']
        if file.filename == '' or not allowed_file(file.filename):
            return jsonify({'success': False, 'error': '请上传PDF文件'}), 400
        
        # 获取参数
        start_page = request.form.get('start_page', 0, type=int)
        end_page = request.form.get('end_page', None, type=int)
        return_json = request.form.get('return_json', 'false').lower() == 'true'
        
        # 保存上传文件
        filename = secure_filename(file.filename)
        temp_id = str(uuid.uuid4())
        pdf_path = os.path.join(UPLOAD_FOLDER, f"{temp_id}_{filename}")
        file.save(temp_path)
        
        # 生成输出文件路径
        output_filename = f"{os.path.splitext(filename)[0]}.docx"
        output_path = os.path.join(OUTPUT_FOLDER, f"{temp_id}_{output_filename}")
        
        try:
            # 执行转换
            cv = Converter(pdf_path)
            cv.convert(output_path, start=start_page, end=end_page)
            cv.close()
            
            # 清理输入文件
            os.remove(pdf_path)
            
            if not os.path.exists(output_path):
                return jsonify({
                    'success': False,
                    'error': '转换失败，未生成输出文件'
                }), 500
            
            # 根据参数返回文件或JSON
            if return_json:
                file_size = os.path.getsize(output_path)
                return jsonify({
                    'success': True,
                    'message': '转换完成',
                    'filename': output_filename,
                    'file_size': file_size,
                    'download_url': f'/api/download/{temp_id}',
                    'temp_id': temp_id,
                    'timestamp': datetime.now().isoformat()
                })
            else:
                # 返回文件
                return send_file(
                    output_path,
                    as_attachment=True,
                    download_name=output_filename,
                    mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document'
                )
            
        except Exception as e:
            # 清理临时文件
            for path in [pdf_path, output_path]:
                if os.path.exists(path):
                    os.remove(path)
            raise e
            
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e),
            'traceback': traceback.format_exc()
        }), 500

@app.route('/api/download/<temp_id>')
def download_file(temp_id):
    """下载转换后的文件"""
    try:
        # 查找文件
        for filename in os.listdir(OUTPUT_FOLDER):
            if filename.startswith(temp_id):
                file_path = os.path.join(OUTPUT_FOLDER, filename)
                original_name = filename.replace(f"{temp_id}_", "")
                
                return send_file(
                    file_path,
                    as_attachment=True,
                    download_name=original_name,
                    mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document'
                )
        
        return jsonify({'success': False, 'error': '文件不存在或已过期'}), 404
        
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/api/batch_convert', methods=['POST'])
def batch_convert():
    """批量转换PDF文件"""
    try:
        if 'files' not in request.files:
            return jsonify({'success': False, 'error': '没有上传文件'}), 400
        
        files = request.files.getlist('files')
        if not files:
            return jsonify({'success': False, 'error': '请选择要转换的PDF文件'}), 400
        
        results = []
        batch_id = str(uuid.uuid4())
        
        for file in files:
            if not allowed_file(file.filename):
                results.append({
                    'filename': file.filename,
                    'success': False,
                    'error': '不是PDF文件'
                })
                continue
            
            try:
                # 保存上传文件
                filename = secure_filename(file.filename)
                temp_id = str(uuid.uuid4())
                pdf_path = os.path.join(UPLOAD_FOLDER, f"{temp_id}_{filename}")
                file.save(pdf_path)
                
                # 生成输出文件路径
                output_filename = f"{os.path.splitext(filename)[0]}.docx"
                output_path = os.path.join(OUTPUT_FOLDER, f"{temp_id}_{output_filename}")
                
                # 执行转换
                cv = Converter(pdf_path)
                cv.convert(output_path)
                cv.close()
                
                # 清理输入文件
                os.remove(pdf_path)
                
                if os.path.exists(output_path):
                    file_size = os.path.getsize(output_path)
                    results.append({
                        'filename': filename,
                        'success': True,
                        'output_filename': output_filename,
                        'file_size': file_size,
                        'download_url': f'/api/download/{temp_id}',
                        'temp_id': temp_id
                    })
                else:
                    results.append({
                        'filename': filename,
                        'success': False,
                        'error': '转换失败'
                    })
                    
            except Exception as e:
                results.append({
                    'filename': file.filename,
                    'success': False,
                    'error': str(e)
                })
        
        return jsonify({
            'success': True,
            'batch_id': batch_id,
            'total_files': len(files),
            'successful_conversions': len([r for r in results if r['success']]),
            'failed_conversions': len([r for r in results if not r['success']]),
            'results': results,
            'timestamp': datetime.now().isoformat()
        })
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

@app.route('/api/status')
def get_status():
    """获取服务状态"""
    try:
        import psutil
        import platform
        
        # 获取系统信息
        cpu_percent = psutil.cpu_percent(interval=1)
        memory = psutil.virtual_memory()
        disk = psutil.disk_usage('/')
        
        # 统计临时文件
        upload_files = len(os.listdir(UPLOAD_FOLDER)) if os.path.exists(UPLOAD_FOLDER) else 0
        output_files = len(os.listdir(OUTPUT_FOLDER)) if os.path.exists(OUTPUT_FOLDER) else 0
        
        return jsonify({
            'success': True,
            'service': 'PDF2DOCX API',
            'status': 'running',
            'timestamp': datetime.now().isoformat(),
            'system_info': {
                'platform': platform.system(),
                'python_version': platform.python_version(),
                'cpu_usage': f"{cpu_percent}%",
                'memory_usage': f"{memory.percent}%",
                'disk_usage': f"{disk.percent}%"
            },
            'temp_files': {
                'upload_folder': upload_files,
                'output_folder': output_files
            },
            'config': {
                'max_file_size': f"{MAX_FILE_SIZE // (1024*1024)}MB",
                'allowed_extensions': list(ALLOWED_EXTENSIONS)
            }
        })
        
    except ImportError:
        # 如果没有psutil，返回基本信息
        return jsonify({
            'success': True,
            'service': 'PDF2DOCX API',
            'status': 'running',
            'timestamp': datetime.now().isoformat(),
            'message': '安装psutil包可获取更详细的系统信息'
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

@app.route('/api/cleanup', methods=['POST'])
def cleanup_temp_files():
    """清理临时文件"""
    try:
        import time
        
        # 获取清理参数
        max_age = request.json.get('max_age_hours', 1) if request.is_json else 1
        max_age_seconds = max_age * 3600
        
        current_time = time.time()
        cleaned_files = []
        
        # 清理上传文件夹
        for folder in [UPLOAD_FOLDER, OUTPUT_FOLDER]:
            if os.path.exists(folder):
                for filename in os.listdir(folder):
                    file_path = os.path.join(folder, filename)
                    if os.path.isfile(file_path):
                        file_age = current_time - os.path.getmtime(file_path)
                        if file_age > max_age_seconds:
                            try:
                                os.remove(file_path)
                                cleaned_files.append(filename)
                            except Exception as e:
                                pass
        
        return jsonify({
            'success': True,
            'message': f'清理完成，删除了{len(cleaned_files)}个文件',
            'cleaned_files': cleaned_files,
            'max_age_hours': max_age,
            'timestamp': datetime.now().isoformat()
        })
        
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

@app.route('/api/health')
def health_check():
    """健康检查接口"""
    try:
        # 测试PDF转换功能
        test_result = {
            'pdf2docx_available': True,
            'fitz_available': True,
            'temp_folders_writable': True
        }
        
        # 检查依赖
        try:
            import pdf2docx
            import fitz
        except ImportError as e:
            test_result['pdf2docx_available'] = False
            test_result['error'] = str(e)
        
        # 检查文件夹权限
        try:
            test_file = os.path.join(UPLOAD_FOLDER, 'test.txt')
            with open(test_file, 'w') as f:
                f.write('test')
            os.remove(test_file)
        except Exception:
            test_result['temp_folders_writable'] = False
        
        all_healthy = all(test_result.values())
        
        return jsonify({
            'success': True,
            'healthy': all_healthy,
            'service': 'PDF2DOCX API',
            'version': '1.0.0',
            'timestamp': datetime.now().isoformat(),
            'checks': test_result
        }), 200 if all_healthy else 503
        
    except Exception as e:
        return jsonify({
            'success': False,
            'healthy': False,
            'error': str(e)
        }), 503

@app.errorhandler(413)
def too_large(e):
    """文件过大处理"""
    return jsonify({
        'success': False,
        'error': f'文件过大，最大支持{MAX_FILE_SIZE // (1024*1024)}MB'
    }), 413

if __name__ == '__main__':
    print("=== PDF2DOCX API服务 ===")
    print(f"📁 临时目录: {UPLOAD_FOLDER}, {OUTPUT_FOLDER}")
    print(f"📊 最大文件: {MAX_FILE_SIZE // (1024*1024)}MB")
    print("🚀 启动服务: http://localhost:5000")
    
    app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE
    app.run(host='0.0.0.0', port=5000, debug=True)